﻿// Principia
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System.Collections.Generic;

namespace Principia.Core.Parsing.ContextFree.LR
{
    public class ItemComparer : IComparer<Item>
    {
        #region IComparer<Item> Members

        public int Compare(Item x, Item y)
        {
            if (x == y) return 0;

            if (x.Position != y.Position)
                return x.Position - y.Position;

            var LookaheadCmp = Compare(x.Lookahead, y.Lookahead);

            if (LookaheadCmp != 0)
                return LookaheadCmp;

            var HeadCmp = Compare(x.Production.Head, y.Production.Head);

            if (HeadCmp != 0)
                return HeadCmp;

            var xSym = x.Production.Symbols;
            var ySym = y.Production.Symbols;

            if (xSym.Length != ySym.Length)
                return xSym.Length - ySym.Length;

            for (var i = 0; i < xSym.Length; i++)
            {
                var Cmp = Compare(xSym[i], ySym[i]);

                if (Cmp != 0)
                    return Cmp;
            }

            return 0;
        }

        #endregion

        private static int Compare(ISymbol x, ISymbol y)
        {
            if (x == y)
                return 0;

            if (x == null)
                return -1;
            if (y == null)
                return 1;

            return x.Name.CompareTo(y.Name);
        }
    }
}